package com.browser.ui;

import com.browser.bookmark.Bookmark;
import com.browser.core.BrowserCore;
import com.browser.core.BrowserTab;
import com.browser.download.DownloadTask;
import com.browser.history.HistoryEntry;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Modality;
import javafx.stage.Stage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import lombok.Data;
import javafx.collections.FXCollections;
import javafx.animation.PauseTransition;
import javafx.util.Duration;
import javafx.collections.ListChangeListener;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.application.Platform;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.image.Image;
import javafx.scene.image.WritableImage;
import javafx.stage.FileChooser;

@Data
public class BrowserWindow {
    private static final Logger logger = LoggerFactory.getLogger(BrowserWindow.class);
    
    private final BorderPane root;
    private final TabPane tabPane;
    private final TextField addressBar;
    private final BrowserCore browserCore;
    private final ProgressIndicator loadingIndicator;
    private final HBox toolbar;

    public BrowserWindow() {
        this.root = new BorderPane();
        this.tabPane = new TabPane();
        this.addressBar = new TextField();
        this.browserCore = new BrowserCore();
        this.loadingIndicator = new ProgressIndicator();
        this.toolbar = createToolbar();
        
        initializeUI();
        setupKeyboardShortcuts();
        enableTabDragging();
    }

    private void initializeUI() {
        root.setTop(toolbar);
        root.setCenter(tabPane);
        
        // 添加标签页切换监听器
        tabPane.getSelectionModel().selectedItemProperty().addListener((obs, oldTab, newTab) -> {
            if (newTab != null) {
                BrowserTab browserTab = (BrowserTab) newTab.getContent().getUserData();
                // 更新地址栏显示当前标签页的URL
                addressBar.setText(browserTab.getCurrentUrl());
                
                // 更新标签页标题
                if (browserTab.getTitle() != null && !browserTab.getTitle().isEmpty()) {
                    newTab.setText(browserTab.getTitle());
                }
            }
        });
        
        createNewTab();
    }

    private HBox createToolbar() {
        HBox toolbar = new HBox(5);
        toolbar.getStyleClass().addAll("toolbar");
        toolbar.setPadding(new Insets(5));
        
        // 导航按钮
        Button backButton = new Button("←");
        backButton.getStyleClass().add("nav-button");
        backButton.setTooltip(new Tooltip("后退"));

        Button forwardButton = new Button("→");
        forwardButton.getStyleClass().add("nav-button");
        forwardButton.setTooltip(new Tooltip("前进"));

        Button refreshButton = new Button("⟳");
        refreshButton.getStyleClass().add("nav-button");
        refreshButton.setTooltip(new Tooltip("刷新"));
        
        // 禁用按钮，直到有历史记录
        backButton.setDisable(true);
        forwardButton.setDisable(true);
        
        // 地址栏容器
        HBox addressBarContainer = new HBox(5);
        addressBarContainer.getStyleClass().add("address-bar-container");
        
        // 设置地址栏样式
        addressBar.getStyleClass().add("address-bar");
        addressBar.setPromptText("搜索或输入网址");
        HBox.setHgrow(addressBar, Priority.ALWAYS);
        
        // 加载指示器
        loadingIndicator.setProgress(-1);
        loadingIndicator.setMaxSize(16, 16);
        loadingIndicator.setVisible(false);
        
        // 搜索按钮
        Button searchButton = new Button("🔍");
        searchButton.getStyleClass().add("icon-button");
        searchButton.setTooltip(new Tooltip("搜索"));
        
        // 新标签页按钮
        Button newTabButton = new Button("+");
        newTabButton.getStyleClass().add("nav-button");
        newTabButton.setTooltip(new Tooltip("新建标签页"));

        // 添加主页按钮
        Button homeButton = new Button("⌂");
        homeButton.getStyleClass().add("nav-button");
        homeButton.setTooltip(new Tooltip("主页"));
        homeButton.setOnAction(e -> loadUrl(browserCore.getSettingsManager().getHomepage()));

        // 设置按钮事件
        backButton.setOnAction(e -> {
            BrowserTab currentTab = getCurrentTab();
            if (currentTab != null && currentTab.canGoBack()) {
                currentTab.goBack();
                updateNavigationButtons(backButton, forwardButton);
                // 更新地址栏
                addressBar.setText(currentTab.getCurrentUrl());
            }
        });
        
        forwardButton.setOnAction(e -> {
            BrowserTab currentTab = getCurrentTab();
            if (currentTab != null && currentTab.canGoForward()) {
                currentTab.goForward();
                updateNavigationButtons(backButton, forwardButton);
                // 更新地址栏
                addressBar.setText(currentTab.getCurrentUrl());
            }
        });
        
        refreshButton.setOnAction(e -> {
            BrowserTab currentTab = getCurrentTab();
            if (currentTab != null) {
                currentTab.refresh();
                // 更新地址栏
                addressBar.setText(currentTab.getCurrentUrl());
            }
        });
        
        searchButton.setOnAction(e -> loadUrl(addressBar.getText()));
        addressBar.setOnAction(e -> loadUrl(addressBar.getText()));
        
        newTabButton.setOnAction(e -> createNewTab());
        
        // 修改导航按钮容器
        HBox navButtons = new HBox(5);
        navButtons.setAlignment(Pos.CENTER);
        navButtons.getChildren().addAll(backButton, forwardButton, refreshButton, homeButton);

        // 组装地址栏容器
        addressBarContainer.getChildren().addAll(addressBar, loadingIndicator, searchButton);
        
        // 添加书签按钮
        Button bookmarkButton = new Button("★");
        bookmarkButton.getStyleClass().add("nav-button");
        bookmarkButton.setTooltip(new Tooltip("添加书签"));
        bookmarkButton.setOnAction(e -> addBookmark());

        // 添加下载按钮
        Button downloadButton = new Button("↓");
        downloadButton.getStyleClass().add("nav-button");
        downloadButton.setTooltip(new Tooltip("下载"));
        downloadButton.setOnAction(e -> showDownloads());

        // 添加设置按钮
        Button settingsButton = new Button("⚙");
        settingsButton.getStyleClass().add("nav-button");
        settingsButton.setTooltip(new Tooltip("设置"));
        settingsButton.setOnAction(e -> showSettings());

        // 创建右侧按钮容器
        HBox rightButtons = new HBox(5);
        rightButtons.setAlignment(Pos.CENTER);
        rightButtons.getChildren().addAll(bookmarkButton, downloadButton, settingsButton);

        // 修改工具栏布局
        toolbar.getChildren().addAll(
            navButtons,
            addressBarContainer,
            rightButtons,
            newTabButton
        );
        
        return toolbar;
    }

    private void loadUrl(String url) {
        BrowserTab currentTab = getCurrentTab();
        if (currentTab != null) {
            loadingIndicator.setVisible(true);
            currentTab.loadUrl(url);
            
            // 更新地址栏和标签页的 URL
            addressBar.setText(url);
            currentTab.setCurrentUrl(url);
            
            // 监听加载状态
            currentTab.getWebView().getEngine().getLoadWorker().stateProperty().addListener(
                (obs, oldState, newState) -> {
                    switch (newState) {
                        case SUCCEEDED:
                            loadingIndicator.setVisible(false);
                            // 更新标签页标题
                            Tab tab = tabPane.getSelectionModel().getSelectedItem();
                            String title = currentTab.getWebView().getEngine().getTitle();
                            if (title != null && !title.isEmpty()) {
                                tab.setText(title);
                            } else {
                                // 如果没有标题，使用 URL 作为标题
                                tab.setText(getDisplayUrl(url));
                            }
                            break;
                        case FAILED:
                            loadingIndicator.setVisible(false);
                            showError("加载失败: " + url);
                            break;
                        case CANCELLED:
                            loadingIndicator.setVisible(false);
                            break;
                    }
                }
            );

            // 监听 URL 变化
            currentTab.getWebView().getEngine().locationProperty().addListener(
                (obs, oldLocation, newLocation) -> {
                    if (newLocation != null) {
                        addressBar.setText(newLocation);
                        currentTab.setCurrentUrl(newLocation);
                    }
                }
            );
        }
    }

    // 显示错误提示
    private void showError(String message) {
        Alert alert = new Alert(Alert.AlertType.ERROR);
        alert.setTitle("错误");
        alert.setHeaderText(null);
        alert.setContentText(message);
        alert.show();
    }

    // 获取显示用的 URL（去掉 http:// 和 https:// 前缀）
    private String getDisplayUrl(String url) {
        return url.replaceFirst("^(https?://)", "");
    }

    private void updateNavigationButtons(Button backButton, Button forwardButton) {
        BrowserTab currentTab = getCurrentTab();
        if (currentTab != null) {
            backButton.setDisable(!currentTab.canGoBack());
            forwardButton.setDisable(!currentTab.canGoForward());
        }
    }

    private void createNewTab() {
        BrowserTab browserTab = new BrowserTab(browserCore);
        Tab tab = new Tab("New Tab", browserTab.getContent());
        
        // 添加关闭确认
        tab.setOnCloseRequest(event -> {
            if (browserTab.getCurrentUrl() != null && !browserTab.getCurrentUrl().isEmpty()) {
                Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
                alert.setTitle("关闭标签页");
                alert.setHeaderText("确定要关闭此标签页吗？");
                alert.setContentText("当前页面: " + browserTab.getTitle());

                if (alert.showAndWait().orElse(ButtonType.CANCEL) == ButtonType.CANCEL) {
                    event.consume();
                }
            }
        });

        tab.setClosable(true);
        tabPane.getTabs().add(tab);
        tabPane.getSelectionModel().select(tab);
        addressBar.clear();

        // 如果是第一个标签页，加载主页
        if (tabPane.getTabs().size() == 1) {
            loadUrl(browserCore.getSettingsManager().getHomepage());
        }
    }

    private BrowserTab getCurrentTab() {
        Tab currentTab = tabPane.getSelectionModel().getSelectedItem();
        return (BrowserTab) currentTab.getContent().getUserData();
    }

    public void show(Stage stage) {
        Scene scene = new Scene(root, 1200, 800);
        scene.getStylesheets().add(getClass().getResource("/styles/browser.css").toExternalForm());
        stage.setScene(scene);
        stage.setTitle("Simple Browser");
        
        // 设置窗口控制
        stage.maximizedProperty().addListener((obs, wasMaximized, isMaximized) -> {
            toolbar.setPadding(new Insets(isMaximized ? 0 : 5));
        });

        // 添加窗口关闭事件处理
        stage.setOnCloseRequest(event -> {
            // 清理资源
            browserCore.shutdown();
            // 确保程序完全退出
            Platform.exit();
            System.exit(0);
        });
        
        stage.show();
    }

    // 添加标签页拖拽功能
    private void enableTabDragging() {
        // JavaFX 8 不支持 TabDragPolicy，所以我们使用事件处理来实现拖拽
        final Delta dragDelta = new Delta();
        
        for (Tab tab : tabPane.getTabs()) {
            enableTabDrag(tab, dragDelta);
        }
        
        // 监听新添加的标签页
        tabPane.getTabs().addListener((ListChangeListener<Tab>) c -> {
            while (c.next()) {
                if (c.wasAdded()) {
                    c.getAddedSubList().forEach(tab -> enableTabDrag(tab, dragDelta));
                }
            }
        });
    }

    private void enableTabDrag(Tab tab, Delta dragDelta) {
        // 为标签页添加一个默认的图标
        if (tab.getGraphic() == null) {
            Label label = new Label();
            label.setMaxWidth(Region.USE_PREF_SIZE);
            tab.setGraphic(label);
        }

        Node graphic = tab.getGraphic();
        graphic.setOnMousePressed(event -> {
            dragDelta.x = event.getSceneX();
            dragDelta.index = tabPane.getTabs().indexOf(tab);
        });

        graphic.setOnMouseDragged(event -> {
            double draggedX = event.getSceneX();
            int currentIndex = tabPane.getTabs().indexOf(tab);
            
            if (draggedX < dragDelta.x && currentIndex > 0) {
                // 向左拖动
                Tab temp = tabPane.getTabs().get(currentIndex - 1);
                tabPane.getTabs().set(currentIndex - 1, tab);
                tabPane.getTabs().set(currentIndex, temp);
                dragDelta.index--;
            } else if (draggedX > dragDelta.x && currentIndex < tabPane.getTabs().size() - 1) {
                // 向右拖动
                Tab temp = tabPane.getTabs().get(currentIndex + 1);
                tabPane.getTabs().set(currentIndex + 1, tab);
                tabPane.getTabs().set(currentIndex, temp);
                dragDelta.index++;
            }
            
            dragDelta.x = draggedX;
        });
    }

    // 用于存储拖拽状态的辅助类
    private static class Delta {
        double x;
        int index;
    }

    private void setupKeyboardShortcuts() {
        root.setOnKeyPressed(event -> {
            if (event.isControlDown()) {
                switch (event.getCode()) {
                    case T:
                        createNewTab();
                        break;
                    case W:
                        closeCurrentTab();
                        break;
                    case R:
                        getCurrentTab().refresh();
                        break;
                    case L:
                        addressBar.requestFocus();
                        addressBar.selectAll();
                        break;
                }
            }
        });
    }

    private void closeCurrentTab() {
        Tab currentTab = tabPane.getSelectionModel().getSelectedItem();
        if (currentTab != null && currentTab.isClosable()) {
            tabPane.getTabs().remove(currentTab);
        }
    }

    private void addBookmark() {
        BrowserTab currentTab = getCurrentTab();
        if (currentTab != null && currentTab.getCurrentUrl() != null) {
            Dialog<ButtonType> dialog = new Dialog<>();
            dialog.setTitle("添加书签");
            dialog.setHeaderText("将当前页面添加到书签");

            GridPane grid = new GridPane();
            grid.setHgap(10);
            grid.setVgap(10);
            grid.setPadding(new Insets(20, 150, 10, 10));

            TextField titleField = new TextField(currentTab.getTitle());
            TextField urlField = new TextField(currentTab.getCurrentUrl());

            grid.add(new Label("标题:"), 0, 0);
            grid.add(titleField, 1, 0);
            grid.add(new Label("网址:"), 0, 1);
            grid.add(urlField, 1, 1);

            dialog.getDialogPane().setContent(grid);
            dialog.getDialogPane().getButtonTypes().addAll(ButtonType.OK, ButtonType.CANCEL);

            if (dialog.showAndWait().orElse(ButtonType.CANCEL) == ButtonType.OK) {
                browserCore.getBookmarkManager().addBookmark(
                    urlField.getText(),
                    titleField.getText(),
                    "root"
                );
            }
        }
    }

    private void showDownloads() {
        Stage downloadStage = new Stage();
        downloadStage.setTitle("下载");
        downloadStage.initOwner(root.getScene().getWindow());
        downloadStage.initModality(Modality.WINDOW_MODAL);

        ListView<DownloadTask> downloadList = new ListView<>();
        downloadList.setItems(FXCollections.observableArrayList(
            browserCore.getDownloadManager().getDownloads()
        ));

        downloadStage.setScene(new Scene(new BorderPane(downloadList), 400, 300));
        downloadStage.show();
    }

    private void showSettings() {
        Stage settingsStage = new Stage();
        settingsStage.setTitle("设置");
        settingsStage.initOwner(root.getScene().getWindow());
        settingsStage.initModality(Modality.WINDOW_MODAL);

        TabPane settingsPane = new TabPane();
        settingsPane.getTabs().addAll(
            createGeneralSettingsTab(),
            createPrivacySettingsTab(),
            createAboutTab()
        );

        settingsStage.setScene(new Scene(settingsPane, 500, 400));
        settingsStage.show();
    }

    private Tab createGeneralSettingsTab() {
        Tab tab = new Tab("常规");
        tab.setClosable(false);

        GridPane grid = new GridPane();
        grid.setHgap(10);
        grid.setVgap(10);
        grid.setPadding(new Insets(20));

        TextField homepageField = new TextField(browserCore.getSettingsManager().getHomepage());
        grid.add(new Label("主页:"), 0, 0);
        grid.add(homepageField, 1, 0);

        Button saveButton = new Button("保存");
        saveButton.setOnAction(e -> {
            browserCore.getSettingsManager().setHomepage(homepageField.getText());
            // 显示保存成功提示
            showNotification("设置已保存");
        });

        grid.add(saveButton, 1, 2);
        tab.setContent(grid);
        return tab;
    }

    private void showNotification(String message) {
        Tooltip tooltip = new Tooltip(message);
        tooltip.setAutoHide(true);
        tooltip.show(root.getScene().getWindow());
        PauseTransition delay = new PauseTransition(Duration.seconds(2));
        delay.setOnFinished(e -> tooltip.hide());
        delay.play();
    }

    private Tab createPrivacySettingsTab() {
        Tab tab = new Tab("隐私");
        tab.setClosable(false);

        GridPane grid = new GridPane();
        grid.setHgap(10);
        grid.setVgap(10);
        grid.setPadding(new Insets(20));

        CheckBox jsCheckBox = new CheckBox("启用 JavaScript");
        jsCheckBox.setSelected(browserCore.getSettingsManager().isJavaScriptEnabled());
        
        CheckBox cookiesCheckBox = new CheckBox("启用 Cookies");
        cookiesCheckBox.setSelected(browserCore.getSettingsManager().isCookiesEnabled());

        Button clearCacheButton = new Button("清除缓存");
        clearCacheButton.setOnAction(e -> {
            browserCore.getCacheManager().clearAll();
            showNotification("缓存已清除");
        });

        Button clearHistoryButton = new Button("清除历史记录");
        clearHistoryButton.setOnAction(e -> {
            browserCore.getHistoryManager().clearHistory();
            showNotification("历史记录已清除");
        });

        grid.add(jsCheckBox, 0, 0);
        grid.add(cookiesCheckBox, 0, 1);
        grid.add(clearCacheButton, 0, 2);
        grid.add(clearHistoryButton, 0, 3);

        tab.setContent(grid);
        return tab;
    }

    private Tab createAboutTab() {
        Tab tab = new Tab("关于");
        tab.setClosable(false);

        VBox content = new VBox(10);
        content.setPadding(new Insets(20));
        content.getChildren().addAll(
            new Label("Simple Browser"),
            new Label("Version 1.0"),
            new Label("A lightweight web browser built with JavaFX")
        );

        tab.setContent(content);
        return tab;
    }

    private void createBookmarkSidebar() {
        VBox sidebar = new VBox(10);
        sidebar.setPadding(new Insets(10));
        sidebar.setPrefWidth(250);
        sidebar.getStyleClass().add("bookmark-sidebar");

        // 添加标题
        Label title = new Label("收藏夹");
        title.getStyleClass().add("sidebar-title");

        // 创建书签列表
        ListView<Bookmark> bookmarkList = new ListView<>();
        bookmarkList.setItems(FXCollections.observableArrayList(
            browserCore.getBookmarkManager().getBookmarks()
        ));

        // 自定义单元格显示
        bookmarkList.setCellFactory(lv -> new ListCell<Bookmark>() {
            @Override
            protected void updateItem(Bookmark bookmark, boolean empty) {
                super.updateItem(bookmark, empty);
                if (empty || bookmark == null) {
                    setText(null);
                    setGraphic(null);
                } else {
                    setText(bookmark.getTitle());
                    setOnMouseClicked(e -> {
                        if (e.getClickCount() == 2) {
                            loadUrl(bookmark.getUrl());
                        }
                    });
                }
            }
        });

        sidebar.getChildren().addAll(title, bookmarkList);
        
        // 添加到主界面
        root.setLeft(sidebar);
    }

    private void showHistory() {
        Stage historyStage = new Stage();
        historyStage.setTitle("历史记录");
        historyStage.initOwner(root.getScene().getWindow());
        historyStage.initModality(Modality.WINDOW_MODAL);

        VBox content = new VBox(10);
        content.setPadding(new Insets(20));

        ListView<HistoryEntry> historyList = new ListView<>();
        historyList.setItems(FXCollections.observableArrayList(
            browserCore.getHistoryManager().getHistory()
        ));

        historyList.setCellFactory(lv -> new ListCell<HistoryEntry>() {
            @Override
            protected void updateItem(HistoryEntry entry, boolean empty) {
                super.updateItem(entry, empty);
                if (empty || entry == null) {
                    setText(null);
                } else {
                    setText(entry.getTitle() + "\n" + entry.getUrl());
                    setOnMouseClicked(e -> {
                        if (e.getClickCount() == 2) {
                            loadUrl(entry.getUrl());
                            historyStage.close();
                        }
                    });
                }
            }
        });

        content.getChildren().add(historyList);
        historyStage.setScene(new Scene(content, 600, 400));
        historyStage.show();
    }

    private void setupSearchSuggestions() {
        ListView<String> suggestionList = new ListView<>();
        suggestionList.setPrefHeight(200);
        suggestionList.setVisible(false);
        suggestionList.getStyleClass().add("suggestion-list");
        
        // 创建一个容器来包含地址栏和建议列表
        VBox addressContainer = new VBox();
        addressContainer.getChildren().addAll(addressBar, suggestionList);
        
        // 添加延迟，避免频繁请求
        PauseTransition delay = new PauseTransition(Duration.millis(300));
        
        addressBar.textProperty().addListener((obs, oldText, newText) -> {
            delay.setOnFinished(e -> {
                if (newText != null && !newText.isEmpty()) {
                    browserCore.getSearchManager().getSuggestions(newText)
                        .thenAcceptAsync(suggestions -> {
                            Platform.runLater(() -> {
                                suggestionList.setItems(FXCollections.observableArrayList(suggestions));
                                suggestionList.setVisible(!suggestions.isEmpty());
                            });
                        });
                } else {
                    suggestionList.setVisible(false);
                }
            });
            delay.playFromStart();
        });

        // 点击建议项时加载对应URL
        suggestionList.setOnMouseClicked(e -> {
            String selected = suggestionList.getSelectionModel().getSelectedItem();
            if (selected != null) {
                String searchUrl = browserCore.getSearchManager().getSearchUrl(selected);
                loadUrl(searchUrl);
                suggestionList.setVisible(false);
            }
        });

        // 当地址栏失去焦点时隐藏建议列表
        addressBar.focusedProperty().addListener((obs, oldFocused, newFocused) -> {
            if (!newFocused) {
                // 添加短暂延迟，以便能够处理点击事件
                PauseTransition hideDelay = new PauseTransition(Duration.millis(200));
                hideDelay.setOnFinished(e -> suggestionList.setVisible(false));
                hideDelay.play();
            }
        });
    }

    private void setupZoomControls() {
        Button zoomInButton = new Button("+");
        Button zoomOutButton = new Button("-");
        Label zoomLabel = new Label("100%");

        zoomInButton.setOnAction(e -> {
            BrowserTab currentTab = getCurrentTab();
            if (currentTab != null) {
                double zoom = currentTab.getWebView().getZoom();
                currentTab.getWebView().setZoom(zoom * 1.1);
                zoomLabel.setText(String.format("%.0f%%", zoom * 110));
            }
        });

        zoomOutButton.setOnAction(e -> {
            BrowserTab currentTab = getCurrentTab();
            if (currentTab != null) {
                double zoom = currentTab.getWebView().getZoom();
                currentTab.getWebView().setZoom(zoom / 1.1);
                zoomLabel.setText(String.format("%.0f%%", zoom * 90));
            }
        });

        HBox zoomControls = new HBox(5, zoomOutButton, zoomLabel, zoomInButton);
        zoomControls.setAlignment(Pos.CENTER);
        toolbar.getChildren().add(zoomControls);
    }

    private void captureScreenshot() {
        BrowserTab currentTab = getCurrentTab();
        if (currentTab != null) {
            WritableImage image = currentTab.getWebView().snapshot(null, null);
            
            FileChooser fileChooser = new FileChooser();
            fileChooser.setTitle("保存截图");
            fileChooser.getExtensionFilters().add(
                new FileChooser.ExtensionFilter("PNG files (*.png)", "*.png")
            );
            
            File file = fileChooser.showSaveDialog(root.getScene().getWindow());
            if (file != null) {
                try {
                    ImageIO.write(SwingFXUtils.fromFXImage(image, null), "png", file);
                    showNotification("截图已保存");
                } catch (IOException e) {
                    showError("保存截图失败: " + e.getMessage());
                }
            }
        }
    }
} 